package com.sam.common.utils;


import org.apache.commons.lang3.StringUtils;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;

/**
 * @classname: DateTool
 * @description: 日期、时间相关的一些常用工具方法.
 * @Author: sam
 * @date: 2021/4/26 15:57
 */
public final class DateTool {

    public static final String DATE_FORMAT = "yyyy-MM-dd HH:mm:ss";

    public static void main(String[] args) throws Exception{
        /*String curDate="2013-09-19 14:22:30";

        String timeZoneId="America/Los_Angeles";
        System.out.println("======================");
        System.out.println(getLocalTime(curDate,timeZoneId));

        String curDateTime="2013-09-19 14:22";
        String formatStr="yyyy-MM-dd HH:mm";
        System.out.println("======================");
        System.out.println(getLocalTime(curDateTime,formatStr,timeZoneId));

        String curTime="14:22";
        String timeFormatStr="HH:mm";
        System.out.println("============HH:mm==========");
        System.out.println(getLocalTime(curTime,timeFormatStr,timeZoneId));

        System.out.println("======================");
        System.out.println(getCurrentLocalTime(timeZoneId));

        System.out.println("==========date current to timeZoneId convert============");
        Date date = new Date();
        String london = "Europe/London";
        System.out.println("当前日期："+date);
        System.out.println(timeZoneTransfer(date, null, timeZoneId));
        System.out.println(timeZoneTransfer(date, null, london));

        System.out.println("==========String current to timeZoneId convert============");
        System.out.println("当前日期curDateTime："+curDateTime);
        System.out.println(timeZoneTransfer(curDateTime, formatStr,null, timeZoneId));
        System.out.println(timeZoneTransfer(curDateTime, formatStr, null, london));*/

        String yearMonth="2021-04";
        String firstDay = getFirstDay(yearMonth, "yyyy-MM");
        String lastDay = getLastDay(yearMonth, "yyyy-MM");
        System.out.println(firstDay);
        System.out.println(lastDay);
    }

    public static String getFirstDay(String yearMonth,String format){
        try {
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat(format);
            Date date = simpleDateFormat.parse(yearMonth);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMinimum(Calendar.DAY_OF_MONTH));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.format(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

    public static String getLastDay(String yearMonth,String format){
        try {
            SimpleDateFormat simpleDateFormat=new SimpleDateFormat(format);
            Date date = simpleDateFormat.parse(yearMonth);
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(date);
            calendar.set(Calendar.DAY_OF_MONTH, calendar.getActualMaximum(Calendar.DAY_OF_MONTH));
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            return sdf.format(calendar.getTime());
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }


    public static String getLocalTime(String dateTimeStr,String timeZoneId)throws Exception{
        DateFormat format =  new SimpleDateFormat(DATE_FORMAT);
        Date date = format.parse(dateTimeStr);

        //模拟前端转换为中国的时间戳
        long tl = date.getTime();
        TimeZone timeZone = TimeZone.getDefault();
        if (StringUtils.isNotBlank(timeZoneId)){
            timeZone = TimeZone.getTimeZone(timeZoneId);
        }
        format.setTimeZone(timeZone);
        String d2 = format.format(tl);
        return d2;
    }

    public static String getLocalTime(String dateTimeStr,String formatStr,String timeZoneId)throws Exception{
        DateFormat format =  new SimpleDateFormat(formatStr);
        Date date = format.parse(dateTimeStr);

        //模拟前端转换为中国的时间戳
        long tl = date.getTime();
        TimeZone timeZone = TimeZone.getDefault();
        if (StringUtils.isNotBlank(timeZoneId)){
            timeZone = TimeZone.getTimeZone(timeZoneId);
        }
        format.setTimeZone(timeZone);
        return format.format(tl);
    }


    /**
     * 根据时区获取当前时间
     * @param timeZoneId
     * @return
     * @throws Exception
     */
    public static String getCurrentLocalTime(String timeZoneId)throws Exception{
        Date curDate = new Date();
        TimeZone timeZone = TimeZone.getDefault();
        if (StringUtils.isNotBlank(timeZoneId)){
            timeZone = TimeZone.getTimeZone(timeZoneId);
        }

        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        simpleDateFormat.setTimeZone(timeZone);
        String time = simpleDateFormat.format(curDate);
        return time;
    }

    /**
     * 时区转换
     * @param dateTime
     * @param formatStr
     * @param currTimeZoneId
     * @param targetTimeZoneId
     * @return
     */
    public static String timeZoneTransfer(String dateTime,String formatStr, String currTimeZoneId,String targetTimeZoneId){
        if (StringUtils.isEmpty(dateTime)) {
            return null;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(formatStr);
        // 源时区
        TimeZone currTimeZone = TimeZone.getDefault();
        if (StringUtils.isNotBlank(currTimeZoneId)){
            currTimeZone = TimeZone.getTimeZone(currTimeZoneId);
        }
        // 目标时区
        TimeZone targetTimeZone = TimeZone.getDefault();
        if (StringUtils.isNotBlank(targetTimeZoneId)){
            targetTimeZone = TimeZone.getTimeZone(targetTimeZoneId);
        }
        simpleDateFormat.setTimeZone(currTimeZone);
        Date date;
        try {
            date = simpleDateFormat.parse(dateTime);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
        simpleDateFormat.setTimeZone(targetTimeZone);

        return simpleDateFormat.format(date);
    }
    /**
     * 时区转换
     * @param dateTime 日期时间
     * @param currTimeZoneId   当前时区
     * @param targetTimeZoneId 目标时区
     * @return
     */
    public static Date timeZoneTransfer(Date dateTime, String currTimeZoneId,String targetTimeZoneId){
        if (dateTime == null) {
            return null;
        }
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(DATE_FORMAT);
        String time = simpleDateFormat.format(dateTime);
        // 源时区
        TimeZone currTimeZone = TimeZone.getDefault();
        if (StringUtils.isNotBlank(currTimeZoneId)){
            currTimeZone = TimeZone.getTimeZone(currTimeZoneId);
        }
        // 目标时区
        TimeZone targetTimeZone = TimeZone.getDefault();
        if (StringUtils.isNotBlank(targetTimeZoneId)){
            targetTimeZone = TimeZone.getTimeZone(targetTimeZoneId);
        }
        simpleDateFormat.setTimeZone(currTimeZone);

        Date date;
        try {
            date = simpleDateFormat.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
            return null;
        }
        simpleDateFormat.setTimeZone(targetTimeZone);
        try {
            dateTime = parse(simpleDateFormat.format(date),DATE_FORMAT);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return dateTime;
    }
    /**
     * 将字符串类型转成日期类型
     *
     * @param dateStr   传入的时间
     * @param formatStr 格式化类型
     * @return
     * @throws ParseException
     */
    public static Date parse(String dateStr, String formatStr) throws ParseException {
        SimpleDateFormat dateFormat = new SimpleDateFormat(formatStr);
        return dateFormat.parse(dateStr);
    }
    /**
     * 将日期类型转成特定格式字符串
     *
     * @param formatStr 格式化类型
     * @param field     日历类型
     * @param offset    偏移量
     * @return
     */
    public static String format(String formatStr, int field, int offset) {
        return format(new Date(), formatStr, field, offset);
    }
    /**
     * 将日期类型转成特定格式字符串
     *
     * @param dateTime  传入的时间
     * @param formatStr 格式化类型
     * @return
     */
    public static String format(Date dateTime, String formatStr) {
        return format(dateTime, formatStr, -1, 0);
    }
    /**
     * 将日期类型转成特定格式字符串
     *
     * @param dateTime  传入的时间
     * @param formatStr 格式化类型
     * @param field     日历类型
     * @param offset    偏移量
     * @return
     */
    public static String format(Date dateTime, String formatStr, int field, int offset) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(dateTime);
        if (field != -1) {
            cal.add(field, offset);
        }
        SimpleDateFormat dateFormat = new SimpleDateFormat(formatStr);
        return dateFormat.format(cal.getTime());
    }
}
